package freespiritsocial.io.user.ui.fragment.mine

import android.graphics.Rect
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.SimpleItemAnimator
import androidx.viewpager2.widget.ViewPager2
import freespiritsocial.io.user.R
import freespiritsocial.io.user.base.BaseFragment
import freespiritsocial.io.user.chat.ChannelManager
import freespiritsocial.io.user.data.UserViewInfo
import freespiritsocial.io.user.data.model.UploadPostEvent.Companion.PublishCancel
import freespiritsocial.io.user.data.model.UploadPostEvent.Companion.PublishCompete
import freespiritsocial.io.user.data.model.UploadPostEvent.Companion.PublishFailed
import freespiritsocial.io.user.data.model.UploadPostEvent.Companion.PublishFinish
import freespiritsocial.io.user.data.model.UploadPostEvent.Companion.PublishReStart
import freespiritsocial.io.user.data.model.UploadPostEvent.Companion.PublishStart
import freespiritsocial.io.user.data.model.UploadPostEvent.Companion.Publishing
import freespiritsocial.io.user.databinding.FrgMineBinding
import freespiritsocial.io.user.ext.circleImageUrlWithBorder
import freespiritsocial.io.user.ext.init
import freespiritsocial.io.user.ext.setNbOnItemChildClickListener
import freespiritsocial.io.user.handle.BackHandle
import freespiritsocial.io.user.ui.adapter.UploadPostAdapter
import freespiritsocial.io.user.ui.fragment.message.ChatFrag.Companion.EXTRA_GROUP_CHANNEL_NAME
import freespiritsocial.io.user.ui.fragment.message.ChatFrag.Companion.EXTRA_GROUP_CHANNEL_URL
import freespiritsocial.io.user.util.CacheUtil
import freespiritsocial.io.user.util.PreViewUtils
import freespiritsocial.io.user.viewmodel.MineViewModel
import freespiritsocial.io.user.weight.BottomCancelDialog
import freespiritsocial.io.user.weight.CancelFollowDialog
import freespiritsocial.io.user.weight.tablayout.listener.OnTabSelectListener
import me.hgj.jetpackmvvm.ext.nav
import me.hgj.jetpackmvvm.ext.navigateAction
import me.hgj.jetpackmvvm.util.StatusBarUtil

/**
 * @description 个人主页
 */
class MineFrg: BaseFragment<MineViewModel,FrgMineBinding>(),OnTabSelectListener {
    companion object {
        const val KEY_IS_USER = "isUser"
        const val KEY_IS_Follow_Page = "page"
        const val KEY_USER = "user"

        //（1：发布的帖子，2：有标签的帖子，3：已保存的帖子--只能查询自己的已保存的帖子）
        const val TYPE_POSTED = 1
        const val TYPE_TAGGED = 2
        const val TYPE_SAVED = 3
    }

    private val fragments: ArrayList<Fragment> by lazy(LazyThreadSafetyMode.NONE) {
        mViewModel.tab.mapIndexedTo(arrayListOf()) { index,_ ->
            MinePostListFrg.create(index + 1,this)
        }
    }

    private var curType = TYPE_POSTED
        set(value) {
            field = value
            mDatabind.viewpager2.currentItem = value - 1
        }

    val preViewUtils: PreViewUtils by lazy(LazyThreadSafetyMode.NONE) {
        val user = mViewModel.user.value
        PreViewUtils(requireActivity(),arrayListOf(UserViewInfo(user?.userAvatar,0)))
    }
    private val uploadPostAdapter by lazy(LazyThreadSafetyMode.NONE) {
        UploadPostAdapter().apply {
            setNbOnItemChildClickListener { adapter,view,position ->
                when (view.id) {
                    R.id.tv_unpublish -> {
                        BottomCancelDialog(requireContext(),message = "Are you sure you want to\nupPublish?") {
                            eventViewModel.uploadEvent.postValue(data[position].also { it.status = PublishCancel })
                        }.show(childFragmentManager,"cancel")
                    }
                    R.id.tv_republish -> eventViewModel.uploadEvent.postValue(data[position].also { it.status = PublishReStart })
                }
            }
        }
    }

    var lastItem = -1

    override fun layoutId(): Int = R.layout.frg_mine

    override fun initView(savedInstanceState: Bundle?) = with(mDatabind) {
        mViewModel.isUser.set(arguments?.getBoolean(KEY_IS_USER,true) ?: true)
        mViewModel.user.value = arguments?.getParcelable(KEY_USER) ?: CacheUtil.getUser()
        model = mViewModel
        click = Click()
        tab.setTabData(mViewModel.tab)
        tab.setOnTabSelectListener(this@MineFrg)
        viewpager2.init(this@MineFrg,fragments,false)
        viewpager2.offscreenPageLimit = fragments.size
        lastItem = viewpager2.currentItem
        viewpager2.registerOnPageChangeCallback(object: ViewPager2.OnPageChangeCallback() {
            override fun onPageSelected(position: Int) {
                super.onPageSelected(position)
                if (lastItem != position) {
                    (fragments.getOrNull(position) as? MinePostListFrg)?.onShow()
                    lastItem = position
                    Log.e("Csw","onPageSelected: $position")
                }
            }
        })
        refresh.clipToOutline = true
        if (mViewModel.isUser.get()) {
            recyclerViewUpload.init(
                uploadPostAdapter,
                hasEmpty = false,
                isScroll = false
            ).also { (it.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false }
            checkUploadFailData()
        } else {
            recyclerViewUpload.isVisible = false
        }
    }

    private fun updatePagerHeightForChild(view: View,pager: ViewPager2) {
        view.post {
            val wMeasureSpec: Int = View.MeasureSpec.makeMeasureSpec(view.width,View.MeasureSpec.EXACTLY)
            val hMeasureSpec: Int = View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED)
            view.measure(wMeasureSpec,hMeasureSpec)
            if (pager.layoutParams.height != view.measuredHeight) {
                val layoutParams: ViewGroup.LayoutParams = pager.layoutParams
                layoutParams.height = view.measuredHeight
                pager.layoutParams = layoutParams
            }
        }
    }

    /**
     * 检查是否有未上传的任务
     */
    private fun checkUploadFailData() {
        uploadPostAdapter.addData(CacheUtil.getUploadEvents())
    }

    override fun createObserver() {
        super.createObserver()
        eventViewModel.attentionEvent.observe(this) {
            val data = mViewModel.user.value
            if (data?.userId == it) {
                data?.changeFollowStatus()
                mViewModel.user.value = data
            }
        }
        appViewModel.userinfo.observe(this) {
            mViewModel.user.value = it
        }
        mViewModel.user.observe(this) {
            if (mDatabind.ivAvatar.tag != it?.userAvatar)
                mDatabind.ivAvatar.circleImageUrlWithBorder(it?.userAvatar,if (mViewModel.isUser.get()) 0 else 2)
        }
        mViewModel.changeViewHeightEvent.observe(this) {
            updatePagerHeightForChild(fragments[mDatabind.viewpager2.currentItem].view ?: return@observe,mDatabind.viewpager2)
        }

        if (mViewModel.isUser.get()) {
            eventViewModel.uploadEvent.observe(this) {
                when (it.status) {
                    Publishing -> uploadPostAdapter.setData(uploadPostAdapter.getItemPosition(it),it)
                    PublishCompete -> {
                        it.status = PublishFinish
                        mViewModel.publishPost(it.postPojo) {
                            uploadPostAdapter.remove(it)
                            fragments.forEach { fragment ->
                                (fragment as MinePostListFrg).onRefresh()
                            }
                            mViewModel.getUserInfo()
                        }
                    }
                    PublishCancel -> {
                        uploadPostAdapter.remove(it)
                    }
                    PublishFailed,PublishStart,PublishReStart -> {
                        val itemPosition = uploadPostAdapter.getItemPosition(it)
                        if (itemPosition >= 0)
                            uploadPostAdapter.setData(itemPosition,it)
                        else
                            uploadPostAdapter.addData(it)
                    }
                }
            }
        }
    }

    override fun onPause() {
        super.onPause()
        StatusBarUtil.darkMode(requireActivity())
    }

    override fun onResume() {
        super.onResume()
        StatusBarUtil.darkMode(requireActivity(),mViewModel.isUser.get())
    }

    override fun dismissLoading() {
        super.dismissLoading()
        mDatabind.refresh.finishLoadMore()
        mDatabind.refresh.finishRefresh()
    }

    //============tab 点击事件==========

    override fun onTabSelect(position: Int) {
        curType = position + 1
    }

    override fun onTabReselect(position: Int) {
    }

    inner class Click: BackHandle {
        fun onRefresh() {
            mViewModel.getUserInfo()
            (fragments.getOrNull(mDatabind.viewpager2.currentItem) as? MinePostListFrg)?.onRefresh()
        }

        fun onMore() {
            (fragments.getOrNull(mDatabind.viewpager2.currentItem) as? MinePostListFrg)?.onLoadMore()
            dismissLoading()
        }

        fun follow() {
            val user = mViewModel.user.value
            if (user?.isFollowed == true)
                CancelFollowDialog(requireContext()) {
                    mViewModel.attention(user.userId,user.isFollowed)
                }.show(childFragmentManager,"cancel follow")
            else {
                mViewModel.attention(user?.userId,user?.isFollowed == true)
            }
        }

        fun message() {
            val userInfo = mViewModel.user.value ?: return
            ChannelManager.createChannel(userInfo.resourceId) { url,nickName ->
                nav().navigateAction(R.id.chatFrag,bundleOf(EXTRA_GROUP_CHANNEL_URL to url,EXTRA_GROUP_CHANNEL_NAME to nickName))
            }
        }

        fun preViewAvatar() {
            val bounds = Rect()
            mDatabind.ivAvatar.getGlobalVisibleRect(bounds)
            preViewUtils.setBounds(bounds)
            preViewUtils.preImage(preViewUtils.imageList.first().url,0)
        }

        fun goFollowers() {
            if (mViewModel.isUser.get())
                nav().navigateAction(R.id.followsFrg,bundleOf(KEY_IS_Follow_Page to 1))
        }

        fun goFollowing() {
            if (mViewModel.isUser.get())
                nav().navigateAction(R.id.followsFrg,bundleOf(KEY_IS_Follow_Page to 0))
        }

        fun goNotify() {
            nav().navigateAction(R.id.action_mainFrg_to_notificationsFrg)
        }

        fun setting() {
            nav().navigateAction(R.id.action_mainFrg_to_settingFrg)
        }

        override fun goBack() {
            nav().navigateUp()
        }

    }
}